function [SS_Timeline, SS_Tasks_Not_Packed] =  SS_Timeline_Brick_Pack(SS_Timeline, SS_Tasks)
%BP_Timeline Summary of this function goes here
%   Detailed explanation goes here

%% Initialisation
max_duration = SS_Timeline.duration - SS_Timeline.lost_time;
SS_Timeline.packed_duration = 0;

%% First determine which tasks are eligable for packing this round
b = 1;
c = 1;
for a = 1:size(SS_Tasks, 2)
  if (SS_Tasks(a).soonest_start_time <= (SS_Timeline.end_time - SS_Tasks(a).max_duration))
    SS_Tasks_Eligible(b) = SS_Tasks(a);
    b = b + 1;
  else
    SS_Tasks_Ineligible(c) = SS_Tasks(a);
    c = c + 1;
  end
end

if ~exist('SS_Tasks_Eligible', 'var')
  SS_Tasks_Not_Packed = SS_Tasks;
  return;
end

%% Sort on epoch goal, then priority and finally max_duration.
s = size(SS_Tasks_Eligible, 2);
for a = 1:s
  c = 0;
  epoch_lowest = Inf;
  priority_lowest = Inf;
  max_duration_lowest = Inf;
  for b = 1:size(SS_Tasks_Eligible, 2)
    if (SS_Tasks_Eligible(b).latest_end_time < epoch_lowest)...
    || ((SS_Tasks_Eligible(b).latest_end_time == epoch_lowest)... 
    && ((SS_Tasks_Eligible(b).priority < priority_lowest)... 
    || ((SS_Tasks_Eligible(b).priority == priority_lowest)...
    && (SS_Tasks_Eligible(b).max_duration < max_duration_lowest))))
      epoch_lowest = SS_Tasks_Eligible(b).latest_end_time;
      priority_lowest = SS_Tasks_Eligible(b).priority;
      max_duration_lowest = SS_Tasks_Eligible(b).max_duration;
      c = b;
    end
  end
  SS_Tasks_Epoch_Priority(a) = SS_Tasks_Eligible(c);
  SS_Tasks_Eligible = [SS_Tasks_Eligible(1:c-1) SS_Tasks_Eligible(c+1:size(SS_Tasks_Eligible, 2))];
end

%% Sub-sort on priority

%% Start Packing based purely on epoch goal, arbitrate with priority
a = 1;
while (SS_Timeline.packed_duration < max_duration) && (a <= size(SS_Tasks_Epoch_Priority, 2))
  SS_Timeline.tasks(a) = SS_Tasks_Epoch_Priority(a);
  SS_Timeline.packed_duration = SS_Timeline.packed_duration + SS_Tasks_Epoch_Priority(a).max_duration;
  a = a + 1;
end

if (SS_Timeline.packed_duration > max_duration)
  SS_Timeline.spill_over_time = SS_Timeline.packed_duration - max_duration;
end

if exist('SS_Tasks_Ineligible', 'var')
  SS_Tasks_Not_Packed = [SS_Tasks_Ineligible SS_Tasks_Epoch_Priority(a:size(SS_Tasks_Epoch_Priority,2))];
else
  SS_Tasks_Not_Packed = SS_Tasks_Epoch_Priority(a:size(SS_Tasks_Epoch_Priority,2));
end

end